package com.maycurobj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maycur.developer.sdk.maycur.ultimate.openapi.entity.AccountEntity;
import com.maycur.developer.sdk.maycur.ultimate.openapi.entity.CityInput;
import com.maycur.developer.sdk.maycur.ultimate.openapi.request.*;
import com.maycur.developer.sdk.maycur.ultimate.openapi.response.*;
import com.maycurobj.domain.PaymentOV;
import com.maycurobj.pojo.*;
import com.maycurobj.service.http.MaycurApiService;
import com.maycurobj.util.NormalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.*;

/**
 * 每刻接口服务
 */
@Service
@Slf4j
public class MeetingService {

    @Autowired
    private MaycurApiService maycurApiService;

    @Autowired
    private MaycurService maycurService;

    /**
     * 生成会议物品领用-报销单
     * 先推送物品领用明细，生成每笔明细的expenseCode
     * 再推送领用主表，关联每笔明细的expenseCode，主表字段为expenseCodes
     * @param maint
     */
    public Map<String, Object> createReceiveWP(MayCurMeetingWPMain maint) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        List<String> expenseCodes = new ArrayList<>();
        //region 先推送物品领用明细，生成每笔明细的expenseCode
        PostReceiveExpenseRequest exReq = new PostReceiveExpenseRequest();
        List<PostReceiveExpenseRequest.Payment> paymentList=new ArrayList<>();
        exReq.setEmployeeId(maint.getCoverUserId());

        for(MayCurMeetingWPItems item : maint.getItems()){
            PostReceiveExpenseRequest.Payment payment = new PostReceiveExpenseRequest.Payment();
            Map<String, Object> customObj = new HashMap<>();
            //region 处理明细中的自定义字段
            //物品名称
            customObj.put("CF79",item.getItem_name());
            //客户名称
            customObj.put("CF88",item.getRelated_customers());
            //单价
            Map<String, Object> unit_price = new HashMap<>();
            unit_price.put("amount",item.getUnit_price());
            unit_price.put("currencyCode","CNY");
            customObj.put("CF85",unit_price);
            //数量
            customObj.put("CF81",item.getApplication_quantity());
            //金额
            Map<String, Object> estimated_total = new HashMap<>();
            estimated_total.put("amount",item.getEstimated_total());
            estimated_total.put("currencyCode","CNY");
            customObj.put("CF82",estimated_total);
            //实际采购单价
            Map<String, Object> final_price = new HashMap<>();
            final_price.put("amount",item.getFinal_price());
            final_price.put("currencyCode","CNY");
            customObj.put("CF83",final_price);
            //实际领用数量
            customObj.put("CF84",item.getFinal_quantity());
            //endregion
            payment.setCustomObject(customObj);
            //region 处理明细中的其他字段
            //实际金额
            Map<String, Object> consumeAmount = new HashMap<>();
            consumeAmount.put("amount",item.getFinal_total());
            consumeAmount.put("currencyCode","CNY");
            payment.setConsumeAmount(consumeAmount);
            //领用日期时间戳
            Map<String, Long> consumeTime = new HashMap<>();
            consumeTime.put("currentTime",NormalUtil.dateToLong(item.getFinal_date()));
            payment.setConsumeTime(consumeTime);
            //是否对公费用
            payment.setCorpExpense(false);
            //费用类型业务编码
            payment.setExpenseTypeBizCode("1109");
            //endregion
            paymentList.add(payment);
        }

        for(int q=0;q<paymentList.size();q+=10) {
            List<PostReceiveExpenseRequest.Payment> postList = paymentList.subList(q, Math.min(paymentList.size(), q + 10));
            //将明细放入请求中的ExpenseList
            exReq.setExpenseList(postList);
            //明细字段处理完成，开始推送
            PostReceiveExpenseResponse rspDetail = this.maycurApiService.getMaycurOpenApiClient().execute(exReq);
            Map<String, Object> responseMap = rspDetail.getData();
            if (responseMap.get("errorData") != null) {
                returnMap.put("code", 0);
                returnMap.put("data", "物品领用费用明细推送失败，异常：" + responseMap.get("errorData").toString());
            } else {
                JSONArray jsonArray = (JSONArray) responseMap.get("successData");
                for (int x = 0; x < jsonArray.size(); x++) {
                    JSONObject json = (JSONObject) jsonArray.get(x);
                    expenseCodes.add(json.getString("expenseCode"));
                }
            }
        }
        //endregion

        //region 再推送领用主表，关联每笔明细的expenseCode，主表字段为expenseCodes
        PostReceiveReimburseRequest rbReq = new PostReceiveReimburseRequest();
        //region 处理物品领用主表数据
        //单据类型业务编码
        rbReq.setFormSubTypeBizCode("FT2112041IRBMKG0");
        //提单人的工号
        rbReq.setSubmittedUserEmployeeId(maint.getCoverUserId());
        //报销单事由
        rbReq.setReimburseName(maint.getReimburseName());
        //公司抬头业务编码
        //rbReq.setLegalEntityBizCode("ELC21102113QULS74");
        rbReq.setLegalEntityBizCode(maint.getCompany_code());
        //承担人工号
        rbReq.setCoverUserEmployeeId(maint.getCoverUserId());
        //承担部门业务编码
        rbReq.setCoverDepartmentBizCode(maycurService.getEmployeeDept(maint.getCoverUserId()));
        //处理自定义字段
        Map<Object, Object> customObject =new HashMap<>();
        //预算主体：妇幼产品中心 BU4200
        //customObject.put("CF102","BU4200");
        customObject.put("CF102",maint.getEntity_code());
        //关联会议链接
        Map<String, String> meetingLink = new HashMap<>();
        meetingLink.put("hyperlinkAddress","https://bpm.biosan.cn/form/detail?workflowInstanceId="+maint.getWorkflowInstanceId());
        meetingLink.put("hyperlinkName",maint.getReceiveMeetingName());
        customObject.put("CF192",meetingLink);
        //customObject.put("CF191","https://bpm.biosan.cn/form/detail?workflowInstanceId="+maint.getWorkflowInstanceId());

        rbReq.setCustomObject(customObject);
        //关联费用明细List
        rbReq.setExpenseCodes(expenseCodes);
        //endregion

        //物品领用主表处理完成，开始推送
        PostReceiveReimburseResponse rbResult = this.maycurApiService.getMaycurOpenApiClient().execute(rbReq);
        if(rbResult.getCode().equals("ACK")){
            returnMap.put("code", 1);
            returnMap.put("data", "物品领用推送成功，每刻单据号："+rbResult.getData());
            return returnMap;
        }
        if(rbResult.getCode().equals("NACK")){
            returnMap.put("code", 0);
            returnMap.put("data", "物品领用推送失败，异常信息：" + rbResult.getData());
            return returnMap;
        }
        //endregion

        return returnMap;
    }


    /**
     * 生成会议费用报销-报销单
     * 先推送费用报销费用明细，生成每笔明细的expenseCode
     * 再推送费用报销主表，关联每笔明细的expenseCode，主表字段为expenseCodes
     * @param maint
     */
    public Map<String, Object> createReceiveBX(MayCurMeetingBXMain maint) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        List<String> expenseCodes = new ArrayList<>();
        //获取当前员工的姓名及银行账号
        Map<String,String> accountMap = getBankAccount(maint.getCoverUserId());
        if(accountMap.size()>0) {
            //region 先推送费用报销明细，生成每笔明细的expenseCode
            //PostReceiveExpenseRequest exReq = new PostReceiveExpenseRequest();
            //List<PostReceiveExpenseRequest.Payment> paymentList = new ArrayList<>();
            JSONObject exReqJson = new JSONObject();
            JSONArray paymentArray = new JSONArray();
            //exReq.setEmployeeId(maint.getCoverUserId());
            exReqJson.put("employeeId", maint.getCoverUserId());
            for (MayCurMeetingBXItems item : maint.getItems()) {
                //重写
                PaymentOV payment = new PaymentOV();
                JSONObject _json = new JSONObject();
                Map<String, Object> customObj = new HashMap<>();
                //region 处理明细中的自定义字段
                //客户名称
                //customObj.put("CF41", item.getCustomer_id());
                customObj.put("CF80", item.getCustomer_id());
                customObj.put("CF187", maint.getReceivemeeting());
                //endregion
                payment.setCustomObject(customObj);

                //region 处理明细中的其他字段
                //金额
                Map<String, Object> consumeAmount = new HashMap<>();
                consumeAmount.put("amount", item.getConsumeAmount());
                consumeAmount.put("currencyCode", "CNY");
                payment.setConsumeAmount(consumeAmount);


                //消费城市
                CityInput cityInput = new CityInput();
                cityInput.setCityPair(null);
                cityInput.setLocation(item.getConsumeLocation_id());
                payment.setConsumeLocation(cityInput);

                //是否对公费用
                payment.setCorpExpense(false);
                //预算科目
                Map<String, String> expenseTypeBizCode = new HashMap<>();
                expenseTypeBizCode.put("国际", "1104");
                expenseTypeBizCode.put("全国", "1103");
                expenseTypeBizCode.put("省级", "1102");
                expenseTypeBizCode.put("市级", "1101");
                expenseTypeBizCode.put("专题", "1107");
                payment.setExpenseTypeBizCode(expenseTypeBizCode.get(maint.getExpenseTypeBizCode()));
                //发票项目（U8）业务编码
                //payment.setViceExpenseTypeCode(payment.getExpenseTypeBizCode());
                //endregion
                //消费日期 格式
                Map<String, Object> consumeTime = new HashMap<>();
                //放置开始时间
                Map<String, Long> timeRange = new HashMap<>();
                timeRange.put("endDate", NormalUtil.dateToLong(item.getEndDate()));
                timeRange.put("startDate", NormalUtil.dateToLong(item.getStartDate()));
                consumeTime.put("timeRange", timeRange);
                _json = JSONObject.parseObject(JSONObject.toJSONString(payment));
                _json.put("consumeTime", JSONObject.parseObject(JSONObject.toJSONString(consumeTime)));
                //发票项目（U8）业务编码
                _json.put("viceExpenseTypeCode", expenseTypeBizCode.get(maint.getExpenseTypeBizCode()));

                //paymentList.add(payment);
                paymentArray.add(_json);
            }

//            for(int q=0;q<paymentArray.size();q+=10) {
//                //List<PostReceiveExpenseRequest.Payment> postList = paymentList.subList(q, Math.min(paymentList.size(), q + 10));
//                //JSONArray postArray = (JSONArray) paymentArray.subList(q, Math.min(paymentArray.size(), q + 10));
//                JSONArray postArray = JSON.parseArray(JSONObject.toJSONString(paymentArray.subList(q, Math.min(paymentArray.size(), q + 10))));
//                //将明细放入请求中的ExpenseList
//                //exReq.setExpenseList(paymentList);
//                exReqJson.put("expenseList", postArray);
//                //明细表组合完成,自定义推送
//                String ret = pushReceiveSelf(exReqJson);
//                //需要对返回结果进行处理
//                JSONObject response = JSONObject.parseObject(ret);
//                //Map<String, Object> responseMap = null;
//                if (response.get("code").toString().equals("NACK")) {
//                    returnMap.put("code", 0);
//                    returnMap.put("data", "费用报销费用明细推送失败，异常：" + ret);
//
//                    return null;
//                } else {
//                    JSONObject data = JSONObject.parseObject(response.get("data").toString());
//                    JSONArray jsonArray = (JSONArray) data.get("successData");
//                    for (int x = 0; x < jsonArray.size(); x++) {
//                        JSONObject json = (JSONObject) jsonArray.get(x);
//                        expenseCodes.add(json.getString("expenseCode"));
//                        //导入发票：
//                        //先获取当前为导入的第几个费用idx
//                        int idx = json.getInteger("idx");
//                        if (!StringUtils.isEmpty(maint.getItems().get(idx).getRefId())) {
//                            String refId = maint.getItems().get(idx).getRefId();
//                            String fileExtension = maint.getItems().get(idx).getFileExtension();
//                            if (refId.contains(",")) {
//                                for (int i = 0; i < refId.split(",").length; i++) {
//                                    String resultData = createinvoice(refId.split(",")[i], fileExtension.split(",")[i], maint.getCoverUserId(), json.getString("expenseCode"));
//                                    log.info("费用报销第" + (idx + 1) + "个费用的第" + (i + 1) + "个发票推送结果", resultData);
//                                }
//                            } else {
//                                String resultData = createinvoice(refId, fileExtension, maint.getCoverUserId(), json.getString("expenseCode"));
//                                log.info("费用报销第" + (idx + 1) + "个费用的发票推送结果", resultData);
//                            }
//                        }
//                    }
//                }
//            }

            for(int q=0;q<paymentArray.size();q++) {

                JSONArray postArray = new JSONArray();
                postArray.add(JSONObject.parseObject(JSONObject.toJSONString(paymentArray.get(q))));
                //将明细放入请求中的ExpenseList
                exReqJson.put("expenseList", postArray);
                //明细表组合完成,自定义推送
                String ret = pushReceiveSelf(exReqJson);
                //需要对返回结果进行处理
                JSONObject response = JSONObject.parseObject(ret);
                //Map<String, Object> responseMap = null;
                if (response.get("code").toString().equals("NACK")) {
                    returnMap.put("code", 0);
                    returnMap.put("data", "费用报销费用明细推送失败，异常：" + ret);

                    return null;
                } else {
                    JSONObject data = JSONObject.parseObject(response.get("data").toString());
                    JSONArray jsonArray = (JSONArray) data.get("successData");
                    JSONObject json = (JSONObject) jsonArray.get(0);
                    expenseCodes.add(json.getString("expenseCode"));

                    if (!StringUtils.isEmpty(maint.getItems().get(q).getRefId())) {
                        String refId = maint.getItems().get(q).getRefId();
                        String fileExtension = maint.getItems().get(q).getFileExtension();
                        if (refId.contains(",")) {
                            for (int i = 0; i < refId.split(",").length; i++) {
                                String resultData = createinvoice(refId.split(",")[i], fileExtension.split(",")[i], maint.getCoverUserId(), json.getString("expenseCode"));
                                log.info("费用报销第" + q + "个费用的第" + (i + 1) + "个发票推送结果", resultData);
                            }
                        } else {
                            String resultData = createinvoice(refId, fileExtension, maint.getCoverUserId(), json.getString("expenseCode"));
                            log.info("费用报销第" + q+ "个费用的发票推送结果", resultData);
                        }
                    }
                }
            }



            //endregion

            //region 再推送费用报销主表，关联每笔明细的expenseCode，主表字段为expenseCodes
            PostReceiveReimburseRequest rbReq = new PostReceiveReimburseRequest();

            //region 处理费用报销主表数据
            //单据类型业务编码
            rbReq.setFormSubTypeBizCode("FT211022144CQR5S");
            //提单人的工号
            rbReq.setSubmittedUserEmployeeId(maint.getCoverUserId());
            //报销单事由
            rbReq.setReimburseName(maint.getPay_reason());
            //公司抬头业务编码
            rbReq.setLegalEntityBizCode(maint.getCompany());
            //承担人工号
            rbReq.setCoverUserEmployeeId(maint.getCoverUserId());
            //承担部门业务编码
            rbReq.setCoverDepartmentBizCode(maycurService.getEmployeeDept(maint.getCoverUserId()));
            //收款账号
            AccountEntity payeeAccount = new AccountEntity();
            payeeAccount.setBankAcctName(accountMap.get("bankAcctName"));
            payeeAccount.setBankAcctNumber(accountMap.get("bankAcctNumber"));
            payeeAccount.setPaymentType("BANK");
            payeeAccount.setAccountType("PERSONAL");
            rbReq.setPayeeAccount(payeeAccount);
            //处理自定义字段
            Map<Object, Object> customObject = new HashMap<>();
            //预算主体：妇幼产品中心 BU4200
            //customObject.put("CF100", "BU4200");
            customObject.put("CF100", maint.getEntity_code());
            //关联会议链接
            Map<String, String> meetingLink = new HashMap<>();
            meetingLink.put("hyperlinkAddress","https://bpm.biosan.cn/form/detail?workflowInstanceId="+maint.getWorkflowInstanceId());
            meetingLink.put("hyperlinkName",maint.getReceivemeeting());
            customObject.put("CF193",meetingLink);
            //是否中台推送
            customObject.put("CF198","RDD39076438709640248");
            rbReq.setCustomObject(customObject);
            //关联费用明细List
            rbReq.setExpenseCodes(expenseCodes);
            //添加每刻接口中不存在的字段
            JSONObject _json = JSONObject.parseObject(JSONObject.toJSONString(rbReq));
            //所属部门
            _json.put("requestDepartmentBizCode",maycurService.getEmployeeDept(maint.getCoverUserId()));
            //endregion

            //费用报销主表处理完成，开始推送
            //PostReceiveReimburseResponse rbResult = this.maycurApiService.getMaycurOpenApiClient().execute(rbReq);
            String ret = pushMaycur("/api/openapi/receive/reimburse",_json);
            //需要对返回结果进行处理
            JSONObject response = JSONObject.parseObject(ret);
            if(response.get("code").toString().equals("ACK")){
                returnMap.put("code", 1);
                returnMap.put("data", "费用报销推送成功，每刻单据号："+response.get("data").toString());
                return returnMap;
            }
            if(response.get("code").toString().equals("NACK")){
                returnMap.put("code", 0);
                returnMap.put("data", "费用报销推送失败，异常信息：" + response.get("data").toString());
                return returnMap;
            }
            //endregion
        }else{
            returnMap.put("code", 1);
            returnMap.put("data", "费用报销推送失败，无法获取员工的银行账号："+accountMap.get("data"));
        }
        return returnMap;
    }


    /**
     * 奥哲附件发票，导入到每刻对应费用下
     * @param refId：奥哲附件id，附件表名：h_biz_attachment
     * @param fileType：附件文件类型，不包含开头的点
     * @param employeeId：员工工号
     * @param expenseCode：费用导入成功后生成的code
     */
    public String createinvoice(String refId, String fileType, String employeeId, String expenseCode) throws Exception {
        JSONObject data=maycurApiService.getToken();
        Map<String,Object> requestdata=new HashMap<>();
        requestdata.put("fileUrl", "https://bpm.biosan.cn/api/api/aliyun/download?refId="+URLEncoder.encode(refId,"UTF-8"));
        log.info("附件URL："+requestdata.get("fileUrl").toString());
        requestdata.put("fileType",fileType);
        requestdata.put("employeeId",employeeId);
        requestdata.put("expenseCode",expenseCode);
        requestdata.put("allInvoiceBindToOneExpense",true);
        String ret=maycurApiService.doPostForMaycur("https://ng.maycur.com/api/openapi/invoice/import-invoice-pic",data,JSONObject.toJSONString(requestdata));
        log.info(ret);

        return ret;
    }

    /**
     * 生成会议对公付款-报销单
     * 先推送对公付款费用明细，生成每笔明细的expenseCode
     * 再推送对公付款主表，关联每笔明细的expenseCode，主表字段为expenseCodes
     * @param maint
     */
    public Map<String, Object> createReceiveFK(MayCurMeetingFKMain maint) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        List<String> expenseCodes = new ArrayList<>();
        //region 先推送对公付款明细，生成每笔明细的expenseCode
        //PostReceiveExpenseRequest exReq = new PostReceiveExpenseRequest();
        //List<PostReceiveExpenseRequest.Payment> paymentList=new ArrayList<>();
        //exReq.setEmployeeId(maint.getCoverUserId());
        JSONObject exReqJson = new JSONObject();
        JSONArray paymentArray = new JSONArray();
        exReqJson.put("employeeId", maint.getCoverUserId());
        for(MayCurMeetingFKItems item : maint.getItems()){
            //重写
            PaymentOV payment = new PaymentOV();
            JSONObject _json = new JSONObject();
            Map<String, Object> customObj = new HashMap<>();
            //region 处理明细中的自定义字段
            //客户名称
            //customObj.put("CF140",item.getCustomer_id());
            customObj.put("CF80",item.getCustomer_id());
            //会议名称-推送文本，取消原每刻的选择字段
            customObj.put("CF188",maint.getReceivemeeting());
            //endregion
            payment.setCustomObject(customObj);


            //region 处理明细中的其他字段
            Map<String, Object> consumeAmount = new HashMap<>();
            consumeAmount.put("amount",item.getThis_pay());
            consumeAmount.put("currencyCode","CNY");
            //本次支付金额
            payment.setConsumeAmount(consumeAmount);

            //业务场景-待确认
            //ALL_RECEIPTS(到票全部支付)
            //NO_RECEIPT(预付未到票)
            //RECEIPT_DEDUCTION(到票核销)
            if(item.getBusiness_scene().equals("到票全部支付")){
                payment.setCorpType("ALL_RECEIPTS");
            }
            if(item.getBusiness_scene().equals("预付未到票")){
                payment.setCorpType("NO_RECEIPT");
            }

            if(item.getBusiness_scene().equals("到票全部支付")){
                //到票时间
                payment.setReceiptDate(NormalUtil.dateToLong(item.getInvoice_arrive_date()));
                //本次到票金额
                Map<String, Object> receiptAmount = new HashMap<>();
                receiptAmount.put("amount",item.getThis_pay());
                receiptAmount.put("currencyCode","CNY");
                payment.setReceiptAmount(receiptAmount);
            }
            if(item.getBusiness_scene().equals("预付未到票")){
                //预计到票时间
                payment.setForecastReceiptDate(NormalUtil.dateToLong(item.getInvoice_arrive_dateplan()));
                //未到票金额
                Map<String, Object> nonReceiptAmount = new HashMap<>();
                nonReceiptAmount.put("amount",item.getNo_arrive_invoice());
                nonReceiptAmount.put("currencyCode","CNY");
                payment.setNonReceiptAmount(nonReceiptAmount);
                //责任人
                Map<String, Object> corpExpenseResponsibleUser = new HashMap<>();
                corpExpenseResponsibleUser.put("userEmpNos",new String[]{maint.getCoverUserId()});
                payment.setCorpExpenseResponsibleUser(corpExpenseResponsibleUser);
            }

            //是否对公费用
            payment.setCorpExpense(true);
            //往来单位业务编码
            payment.setTradingPartnerBizCode(maint.getContact_companyCode());
            //费用类型业务编码
            Map<String, String> expenseTypeBizCode = new HashMap<>();
            expenseTypeBizCode.put("国际","1104");
            expenseTypeBizCode.put("全国","1103");
            expenseTypeBizCode.put("省级","1102");
            expenseTypeBizCode.put("市级","1101");
            expenseTypeBizCode.put("专题","1107");
            payment.setExpenseTypeBizCode(expenseTypeBizCode.get(maint.getExpenseTypeBizCode()));
            //发票项目（U8）业务编码
            //payment.setViceExpenseTypeCode(payment.getExpenseTypeBizCode());
            _json = JSONObject.parseObject(JSONObject.toJSONString(payment));
            //发票项目（U8）业务编码
            _json.put("viceExpenseTypeBizCode", expenseTypeBizCode.get(maint.getExpenseTypeBizCode()));
            //endregion
            //paymentList.add(payment);
            paymentArray.add(_json);

        }
//        for(int q=0;q<paymentArray.size();q+=10) {
//            //List<PostReceiveExpenseRequest.Payment> postList=paymentList.subList(q,Math.min(paymentList.size(),q+10));
//            JSONArray postArray = JSON.parseArray(JSONObject.toJSONString(paymentArray.subList(q, Math.min(paymentArray.size(), q + 10))));
//            //将明细放入请求中的ExpenseList
//            //exReq.setExpenseList(postList);
//            exReqJson.put("expenseList", postArray);
//            //明细字段处理完成，开始推送
//            //PostReceiveExpenseResponse rspDetail = this.maycurApiService.getMaycurOpenApiClient().execute(exReq);
//            //Map<String, Object> responseMap = rspDetail.getData();
//            //明细表组合完成,自定义推送
//            String ret = pushReceiveSelf(exReqJson);
//            //需要对返回结果进行处理
//            JSONObject response = JSONObject.parseObject(ret);
//            //if (responseMap.get("errorData") != null) {
//            if (response.get("code").toString().equals("NACK")) {
//                returnMap.put("code", 0);
//                //returnMap.put("data", "对公付款费用明细推送失败，异常：" + responseMap.get("errorData").toString());
//                returnMap.put("data", "对公付款费用明细推送失败，异常：" + ret);
//            } else {
//                //JSONArray jsonArray = (JSONArray) responseMap.get("successData");
//                JSONObject data = JSONObject.parseObject(response.get("data").toString());
//                JSONArray jsonArray = (JSONArray) data.get("successData");
//                for (int x = 0; x < jsonArray.size(); x++) {
//                    JSONObject json = (JSONObject) jsonArray.get(x);
//                    expenseCodes.add(json.getString("expenseCode"));
//                    //导入发票：
//                    //先获取当前为导入的第几个费用idx
//                    int idx = json.getInteger("idx");
//                    if (!StringUtils.isEmpty(maint.getItems().get(idx).getRefId())) {
//                        String refId = maint.getItems().get(idx).getRefId();
//                        String fileExtension = maint.getItems().get(idx).getFileExtension();
//                        if (refId.contains(",")) {
//                            for (int i = 0; i < refId.split(",").length; i++) {
//                                String resultData = createinvoice(refId.split(",")[i], fileExtension.split(",")[i], maint.getCoverUserId(), json.getString("expenseCode"));
//                                log.info("对公付款第" + (idx + 1) + "个费用的第" + (i + 1) + "个发票推送结果", resultData);
//                            }
//                        } else {
//                            String resultData = createinvoice(refId, fileExtension, maint.getCoverUserId(), json.getString("expenseCode"));
//                            log.info("对公付款第" + (idx + 1) + "个费用的发票推送结果", ret);
//                        }
//                    }
//                }
//            }
//        }
        for(int q=0;q<paymentArray.size();q++) {

            JSONArray postArray = new JSONArray();
            postArray.add(JSONObject.parseObject(JSONObject.toJSONString(paymentArray.get(q))));
            //将明细放入请求中的ExpenseList
            //exReq.setExpenseList(postList);
            exReqJson.put("expenseList", postArray);
            //明细表组合完成,自定义推送
            String ret = pushReceiveSelf(exReqJson);
            //需要对返回结果进行处理
            JSONObject response = JSONObject.parseObject(ret);
            //if (responseMap.get("errorData") != null) {
            if (response.get("code").toString().equals("NACK")) {
                returnMap.put("code", 0);
                returnMap.put("data", "对公付款费用明细推送失败，异常：" + ret);
            } else {
                JSONObject data = JSONObject.parseObject(response.get("data").toString());
                JSONArray jsonArray = (JSONArray) data.get("successData");
                JSONObject json = (JSONObject) jsonArray.get(0);
                expenseCodes.add(json.getString("expenseCode"));

                if (!StringUtils.isEmpty(maint.getItems().get(q).getRefId())) {
                    String refId = maint.getItems().get(q).getRefId();
                    String fileExtension = maint.getItems().get(q).getFileExtension();
                    if (refId.contains(",")) {
                        for (int i = 0; i < refId.split(",").length; i++) {
                            String resultData = createinvoice(refId.split(",")[i], fileExtension.split(",")[i], maint.getCoverUserId(), json.getString("expenseCode"));
                            log.info("对公付款第" + q + "个费用的第" + (i + 1) + "个发票推送结果", resultData);
                        }
                    } else {
                        String resultData = createinvoice(refId, fileExtension, maint.getCoverUserId(), json.getString("expenseCode"));
                        log.info("对公付款第" + q+ "个费用的发票推送结果", resultData);
                    }
                }
            }
        }
        //endregion

        //region 再推送对公付款主表，关联每笔明细的expenseCode，主表字段为expenseCodes
        PostReceiveReimburseRequest rbReq = new PostReceiveReimburseRequest();

        //region 处理对公付款主表数据
        //单据类型业务编码
        rbReq.setFormSubTypeBizCode("FT21102113QWJ3EO");
        //提单人的工号
        rbReq.setSubmittedUserEmployeeId(maint.getCoverUserId());
        //报销单事由
        rbReq.setReimburseName(maint.getPay_reason());
        //公司抬头业务编码
        rbReq.setLegalEntityBizCode(maint.getPay_companyCode());
        //往来单位业务编码
        rbReq.setTradingPartnerBizCode(maint.getContact_companyCode());
        //收款账户
        AccountEntity payeeAccount = new AccountEntity();
        payeeAccount.setBankAcctName(maint.getBankAcctName());
        String bankAcctNumber=maint.getBankAcctNumber().replace(" ","").split("：")[1];
        log.info("银行账号："+bankAcctNumber);
        payeeAccount.setBankAcctNumber(bankAcctNumber);
        //payeeAccount.setBankAcctNumber(maint.getBankAcctNumber());
        payeeAccount.setPaymentType(maint.getPaymentType());
        payeeAccount.setAccountType("CORP");
        rbReq.setPayeeAccount(payeeAccount);
        //承担人工号
        rbReq.setCoverUserEmployeeId(maint.getCoverUserId());
        //承担部门业务编码
        rbReq.setCoverDepartmentBizCode(maycurService.getEmployeeDept(maint.getCoverUserId()));
        //处理自定义字段
        Map<Object, Object> customObject =new HashMap<>();
        //预算主体：妇幼产品中心 BU4200
        //customObject.put("CF113","BU4200");
        customObject.put("CF113",maint.getEntity_code());
        //关联会议链接
        Map<String, String> meetingLink = new HashMap<>();
        meetingLink.put("hyperlinkAddress","https://bpm.biosan.cn/form/detail?workflowInstanceId="+maint.getWorkflowInstanceId());
        meetingLink.put("hyperlinkName",maint.getReceivemeeting());
        customObject.put("CF194",meetingLink);
        //是否中台推送
        customObject.put("CF197","RDD39076438709640248");
        rbReq.setCustomObject(customObject);
        //关联费用明细List
        rbReq.setExpenseCodes(expenseCodes);
        //添加每刻接口中不存在的字段
        JSONObject _json = JSONObject.parseObject(JSONObject.toJSONString(rbReq));
        //所属部门
        _json.put("requestDepartmentBizCode",maycurService.getEmployeeDept(maint.getCoverUserId()));
        //endregion

        //对公付款主表处理完成，开始推送
        //PostReceiveReimburseResponse rbResult = this.maycurApiService.getMaycurOpenApiClient().execute(rbReq);
        String ret = pushMaycur("/api/openapi/receive/reimburse",_json);
        //需要对返回结果进行处理
        JSONObject response = JSONObject.parseObject(ret);
        if(response.get("code").toString().equals("ACK")){
            returnMap.put("code", 1);
            returnMap.put("data", "对公付款推送成功，每刻单据号："+response.get("data").toString());
            return returnMap;
        }
        if(response.get("code").toString().equals("NACK")){
            returnMap.put("code", 0);
            returnMap.put("data", "对公付款推送失败，异常信息：" + response.get("data").toString());
            return returnMap;
        }
        //endregion

        return returnMap;
    }


    /**
     * 生成会议借款申请-借款单
     * @param jkMain
     */
    public Map<String, Object> createReceipt(MayCurMeetingJKMain jkMain) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        PostReceiveLoanRequest rlReq= new PostReceiveLoanRequest();
        //Map<String,Object> accountMap= new HashMap<>();
        //获取当前员工的姓名及银行账号
        Map<String,String> accountMap = getBankAccount(jkMain.getCoverUserId());
        if(accountMap.size()>0){
            AccountEntity payeeAccount = new AccountEntity();
            payeeAccount.setBankAcctName(accountMap.get("bankAcctName"));
            payeeAccount.setBankAcctNumber(accountMap.get("bankAcctNumber"));
            payeeAccount.setPaymentType("BANK");
            payeeAccount.setAccountType("PERSONAL");

            //收款账号
            rlReq.setPayeeAccount(payeeAccount);
            //每刻单据类型业务编码
            rlReq.setFormSubTypeBizCode("FT2111271PQCOYDC");
            //借款申请事由
            rlReq.setLoanName(jkMain.getLoan_reason());
            //企业抬头业务编码，只传博圣的编码
            rlReq.setEntLegalBizCode("ELC21102113QULS74");
            //部门编号
            rlReq.setDepartmentBizCode(maycurService.getEmployeeDept(jkMain.getCoverUserId()));
            //借款人员工编号
            rlReq.setLoanUserEmpNo(jkMain.getCoverUserId());
            //借款金额
            rlReq.setLoanAmount(jkMain.getLoan_amount());
            //预计归还日期(时间戳)
            rlReq.setExpectedPaybackDate(NormalUtil.dateToLong(jkMain.getExpected_repay_date()));
            //处理自定义字段
            Map<Object, Object> customObject =new HashMap<>();
            //借款类别
            customObject.put("CF63","RDD211022YOQ64XS");
            rlReq.setCustomObject(customObject);

            PostReceiveLoanResponse receiveLoanResponse= this.maycurApiService.getMaycurOpenApiClient().execute(rlReq);
            if(receiveLoanResponse.getCode().equals("ACK")){
                returnMap.put("code", 1);
                returnMap.put("data", "会议借款申请推送成功，每刻单据号："+receiveLoanResponse.getData());
                return returnMap;
            }
            if(receiveLoanResponse.getCode().equals("NACK")){
                returnMap.put("code", 0);
                returnMap.put("data", "会议借款申请推送失败，异常信息：" + receiveLoanResponse.getData());
                return returnMap;
            }
        }else{
            returnMap.put("code", 1);
            returnMap.put("data", "推送失败，无法获取员工的银行账号："+accountMap.get("data"));
        }

        return returnMap;
    }

    /**
     * 根据预算主体编码查询预算详细信息
     * 仅限当前季度的预算
     * @param orgBizCode：预算主体编码
     * @param subjectBizCode：预算科目编码
     */
    public JSONObject getBudget(String orgBizCode, String subjectBizCode) throws Exception {
        JSONObject budgetReqJson = new JSONObject();
        Map<String,String> resultMap= new HashMap<>();
        budgetReqJson.put("orgBizCode",orgBizCode);
        budgetReqJson.put("subjectBizCode",subjectBizCode);
        String result=pushMaycur("/api/openapi/budget",budgetReqJson);
        JSONObject resultJsonObject = JSONObject.parseObject(result);
        //请求成功
        if(resultJsonObject.get("code").toString().equals("ACK")){
            JSONArray budgetPlans = resultJsonObject.getJSONObject("data").getJSONArray("budgetPlans");
            Calendar cal = Calendar.getInstance();
            Date date = new Date();
            cal.setTime(date);
            // 获取当前年
            int thisYear = cal.get(Calendar.YEAR);
            //获取当前季度
            int quarter = (cal.get(Calendar.MONTH) / 3) + 1;

            for(Object object : budgetPlans){
                JSONObject budgetPlan= (JSONObject) JSON.toJSON(object);
                //判断是否是当前年份并且生效的季度预算方案
                if(budgetPlan.getString("bizCode").contains(thisYear +"-Q") && budgetPlan.getBoolean("enabled")){
                    //获取当前方案下所有的预算
                    JSONArray budgets = budgetPlan.getJSONArray("budgets");
                    Object budget = budgets.get(0);
                    JSONObject budgetJson= (JSONObject) JSON.toJSON(budget);

                    //获取所有季度的预算详细信息
                    JSONArray budgetUnits = budgetJson.getJSONArray("budgetUnits");
                    for(Object budgetUnitObject: budgetUnits){
                        JSONObject budgetUnitJsonObject= (JSONObject) JSON.toJSON(budgetUnitObject);
                        //确认是否是当前季度的预算
                        if(budgetUnitJsonObject.getInteger("periodNum")==quarter){
                            return budgetUnitJsonObject;
                        }
                    }
                }
            }
        }

        return null;
    }

    /**
     * 根据工号获取每刻中的员工的账户名及银行账号
     * 仅限一个员工的查询
     */
    private Map<String,String> getBankAccount(String coverUserId) throws Exception {
        PostEmployeeDetailsRequest edreq = new PostEmployeeDetailsRequest();
        Map<String,String> resultMap= new HashMap<>();
        List<String> employeeIds = new ArrayList<>();
        String bankAcctNumber="";
        String bankAcctName="";
        employeeIds.add(coverUserId);
        edreq.setEmployeeIds(employeeIds);
        PostEmployeeDetailsResponse eDetailsRes=  this.maycurApiService.getMaycurOpenApiClient().execute(edreq);
        List<PostEmployeeDetailsResponse.UserDetail> eDetailsList=eDetailsRes.getData();
        if(!eDetailsList.get(0).getAccounts().isEmpty()){
            for(PostEmployeeDetailsResponse.Account account : eDetailsList.get(0).getAccounts()){
                if(account.getPaymentType().equals("BANK")){
                    bankAcctName= account.getBankAcctName();
                    bankAcctNumber = account.getBankAcctNumber();

                    resultMap.put("bankAcctName",bankAcctName);
                    resultMap.put("bankAcctNumber",bankAcctNumber);
                    return resultMap;
                }
            }
        }else{
            resultMap.put("code", "0");
            resultMap.put("data", eDetailsRes.getData().toString());
        }
        return resultMap;
    }



    /**
     * 根据往来单位编码获取每刻中的往来单位编码的账户名及银行账号
     * 仅限一个往来单位的查询
     */
    public List<MayCurMeetingPartnerAccountDTO> getTradingPartnerAccount(String bizCodes) throws Exception {
        PostTradingPartnerListRequest tpreq= new PostTradingPartnerListRequest();
        List<MayCurMeetingPartnerAccountDTO> partnerAccountList = new ArrayList<>();
        List<String> bizCodeIds = new ArrayList<>();
        bizCodeIds.add(bizCodes);
        tpreq.setBizCodes(bizCodeIds);
        PostTradingPartnerListResponse eDetailsRes=  this.maycurApiService.getMaycurOpenApiClient().execute(tpreq);
        PostTradingPartnerListResponse.Data eDetailsList=eDetailsRes.getData();

        if(eDetailsList.getTotalRecords()>0){
            for(PostTradingPartnerListResponse.PartnerAccount partnerAccount : eDetailsList.getPartnerList().get(0).getAccounts()){
                if(partnerAccount.getPaymentType().contains("BANK")){
                    MayCurMeetingPartnerAccountDTO meetingPartnerAccountDTO = new MayCurMeetingPartnerAccountDTO();
                    meetingPartnerAccountDTO.setBankAcctName(partnerAccount.getBankAcctName());
                    meetingPartnerAccountDTO.setBankAcctNumber(partnerAccount.getBankName()+"："+partnerAccount.getBankAcctNumber().replaceAll("(.{4})","$1 "));
                    partnerAccountList.add(meetingPartnerAccountDTO);
                }
            }
        }
        return partnerAccountList;
    }


    /**
     * 分页获取往来单位列表
     * pageSize：默认每页50，最大支持100
     * pageNo：分页序号
     */
    public List<MayCurMeetingPartnerDTO> getTradingPartner(int pageNo,int pageSize,String keyword) throws Exception {
        List<MayCurMeetingPartnerDTO> partnerList = new ArrayList<>();

        JSONObject pushBody= new JSONObject();
        pushBody.put("pageNo",pageNo);
        pushBody.put("pageSize",pageSize);
        if(!org.apache.commons.lang3.StringUtils.isEmpty(keyword)){
            pushBody.put("keyword",keyword);
        }
        String ret = pushMaycur("/api/openapi/tradingPartner/list",pushBody);
        JSONObject jsonObject = JSONObject.parseObject(ret);
        if(jsonObject.get("code").toString().equals("ACK")){
            JSONObject resultDataObject = jsonObject.getJSONObject("data");
            JSONArray jsonArray = (JSONArray)resultDataObject.get("partnerList");
            for(Object itemJson : jsonArray){
                JSONObject x = (JSONObject) JSON.toJSON(itemJson);
                MayCurMeetingPartnerDTO customerDTO= new MayCurMeetingPartnerDTO();
                customerDTO.setBizCode(x.getString("bizCode"));
                customerDTO.setName(x.getString("name"));
                partnerList.add(customerDTO);
            }
        }
        return partnerList;
    }

    //获取每刻的公司抬头名称及对应的ID
    public List<MayCurCompanyDTO> getCompany() {
        try {
            List<MayCurCompanyDTO> resultList= new ArrayList();
            String url = "https://ng.maycur.com/api/openapi/legalEntity/data";
            JSONObject tokenInfo = maycurApiService.getToken();
            String ret = maycurApiService.doGetForMaycur(url, tokenInfo);
            JSONObject retJson=JSONObject.parseObject(ret);
            JSONArray dataArray=(JSONArray)retJson.get("data");
            for(Object itemJson : dataArray){
                JSONObject x = (JSONObject) JSON.toJSON(itemJson);
                MayCurCompanyDTO companyob= new MayCurCompanyDTO();
                companyob.setBizCode(x.getString("bizCode"));
                companyob.setInvoiceTitle(x.getString("invoiceTitle"));
                resultList.add(companyob);
            }
            //要对返回结果进行处理
            log.info("自定义请求返回------>{}", ret);
            return resultList;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 分页获取客户档案列表
     * referenceDataBizCode：客户档案编码：RD211118ZNNJFK0
     * pageSize：默认每页50，最大支持100
     * offset：当前页首条数据在所有数据中的偏移量，等于   （页数-1）*pageSize
     */
    public List<MayCurMeetingCustomerDTO> getCustomerList(int pageNum,int pageSize,String keyword) throws Exception {
        List<MayCurMeetingCustomerDTO> customerList = new ArrayList<>();
        JSONObject pushBody= new JSONObject();
        pushBody.put("referenceDataBizCode","RD211118ZNNJFK0");
        pushBody.put("offset",(pageNum-1)*pageSize);
        pushBody.put("pageSize",pageSize);
        if(!org.apache.commons.lang3.StringUtils.isEmpty(keyword)){
            pushBody.put("keyword",keyword);
        }
        String ret = pushMaycur("/api/openapi/reference/data/detail/query",pushBody);
        JSONObject jsonObject = JSONObject.parseObject(ret);
        if(jsonObject.get("code").toString().equals("ACK")){
            JSONObject resultDataObject = jsonObject.getJSONObject("data");
            JSONArray jsonArray = (JSONArray)resultDataObject.get("list");
            for(Object itemJson : jsonArray){
                JSONObject x = (JSONObject) JSON.toJSON(itemJson);
                MayCurMeetingCustomerDTO customerDTO= new MayCurMeetingCustomerDTO();
                customerDTO.setBizCode(x.getString("bizCode"));
                customerDTO.setName(x.getString("name"));
                customerList.add(customerDTO);
            }
        }

        return customerList;
    }

    //自定义推送费用服务 方法
    private String pushReceiveSelf(JSONObject json) {
        try {
            log.info("自定义请求报文------->{}", JSONObject.toJSONString(json));
            String url = "https://ng.maycur.com/api/openapi/receive/expense";
            JSONObject tokenInfo = maycurApiService.getToken();
            String ret = maycurApiService.doPostForMaycur(url, tokenInfo, JSONObject.toJSONString(json));
            //要对返回结果进行处理
            log.info("自定义请求返回------>{}", ret);
            return ret;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    //自定义推送方法
    private String pushMaycur(String url,JSONObject json) {
        try {
            log.info("自定义请求报文------->{}", JSONObject.toJSONString(json));
            String postUrl = "https://ng.maycur.com"+url;
            JSONObject tokenInfo = maycurApiService.getToken();
            String ret = maycurApiService.doPostForMaycur(postUrl, tokenInfo, JSONObject.toJSONString(json));
            //要对返回结果进行处理
            log.info("自定义请求返回------>{}", ret);
            return ret;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }



}
